package org.chen.utils.excel;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.chen.domain.dto.ArticleImportDTO;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Slf4j
public class ExcelReader implements AutoCloseable {
    private final Workbook workbook;
    private final Sheet sheet;
    private int currentRow = 1; // 跳过表头
    private static final int BUFFER_SIZE = 1000;

    public ExcelReader(MultipartFile file) throws IOException {
        workbook = Objects.requireNonNull(file.getOriginalFilename()).endsWith(".xlsx") ?
            new XSSFWorkbook(file.getInputStream()) :
            new HSSFWorkbook(file.getInputStream());
        sheet = workbook.getSheetAt(0);
    }

    public List<ArticleImportDTO.Article> readBatch() {
        List<ArticleImportDTO.Article> articles = new ArrayList<>();
        int endRow = Math.min(currentRow + BUFFER_SIZE, sheet.getLastRowNum() + 1);

        for (; currentRow < endRow; currentRow++) {
            Row row = sheet.getRow(currentRow);
            if (row == null) continue;

            String title = getCellValue(row.getCell(0));
            String description = getCellValue(row.getCell(1));

            if (StringUtils.isNotBlank(title)) {
                ArticleImportDTO.Article article = new ArticleImportDTO.Article();
                article.setTitle(title.trim());
                article.setDescription(StringUtils.trimToEmpty(description));
                article.setTimestamp(LocalDateTime.now().toString());
                articles.add(article);
            }
        }

        return articles;
    }

    public boolean hasNext() {
        return currentRow <= sheet.getLastRowNum();
    }

    @Override
    public void close() throws IOException {
        workbook.close();
    }

    private String getCellValue(Cell cell) {
        if (cell == null) return "";
        
        return switch (cell.getCellType()) {
            case STRING -> cell.getStringCellValue();
            case NUMERIC -> String.valueOf(cell.getNumericCellValue());
            default -> "";
        };
    }
}